import axios from "axios";
import { LLMProvider } from "../llms/modelProvider";
import { HumanMessage } from "@langchain/core/messages";

export interface HSKnowledgeResult {
    count: number;
    token_usage: {
        embedding_token_usage: {
            prompt_tokens: number;
            completion_tokens: number;
            total_tokens: number;
        };
        rerank_token_usage: number;
    };
    result_list: HSKnowledgeResultItem[];
}

interface HSKnowledgeResultItem {
    id: string;
    content: string;
    score: number;
    rerank_score: number;
    table_chunk_fields: {
        field_name: string;
        field_value: string;
    }[];
}


export const HS_ImageGenSize = {
    rate1_1: "2048x2048",
    rate3_4: "1728x2304",
    rate4_3: "2304x1728",
    rate16_9: "2560x1440",
    rate9_16: "1440x2560",
    rate2_3: "1664x2496",
    rate3_2: "2496x1664",
    rate21_9: "2560x1440"
}

interface HSAddSliceParams {
    doc_id: string;
    chunk_type: "structured" | "text" | "faq";
    content?: string;
    chunk_title?: string; //切片标题
    /**
     * 新增 faq 切片中的问题字段
     * 当 chunk_type 为 faq 时必传
     * 字段长度范围为 [1，{Embedding模型支持的最大长度}]
     *
     * @type {string}
     * @memberof HSAddSliceParams
     */
    question?: string;

    /**
     * 表示传入的结构化数据
     * 当 chunk_type 为 structured 时必传。
     *  [
     *  { "field_name": "xxx" // 字段名称
     *  "field_value": xxxx // 字段值
     *  },
     *  ]
     *  field_name 必须已在所属知识库的表字段里配置，否则会报错
     *  和文档导入时的向量字段长度校验保持一致，拼接后的做 embedding 的文本长度不超过 65535
     *
     * @type {{ field_name: string; field_value: string; }[]}
     * @memberof HSAddSliceParams
     */
    fields?: { field_name: string; field_value: string; }[];
}

export class GoodDesignPage {
    userInput: string;
    style: string;
    industry: string;
    content: string;
}

export enum HSKnowledgeService {
    // 图片资源库
    ImageStore = "kb-service-9ec6a78f888624a8",
    GoodDesignStore = "kb-service-2337c076760ee9e"
}

export class HSKnowledge {
    private apiKey = "3d55e44d-c379-4ec0-83cc-6d8993d297da";
    private host = "https://api-knowledgebase.mlp.cn-beijing.volces.com";

    private getReqParams(url: string, data: any) {
        return {
            method: 'post',
            url: `${this.host}/${url}`,
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.apiKey}`,
            },
            data
        }
    }

    async GetKnowledgeList() {
        const url = "api/knowledge/collection/list";
        const req = this.getReqParams(url, {});
        const res = await axios(req);
        const resData = res.data.data;
        return resData;
    }

    private async AddSlice(params: HSAddSliceParams) {
        const url = "api/knowledge/point/add";
        const req = this.getReqParams(url, params);
        const res = await axios(req);
        return res.data.data;
    }

    /**
     * 用于添加良好的设计稿到知识库，以切片的方式
     *
     * @param {GoodDesignPage[]} pages
     * @memberof HSKnowledge
     */
    async AddGoodDesignPageToStore(pages: GoodDesignPage[]) {
        const res: any[] = [];
        for (let item of pages) {
            const reload = await this.AddSlice({
                doc_id: "_sys_auto_gen_doc_id-14692905636908101777",
                chunk_type: "structured",
                fields: Object.keys(item).map(key => {
                    return {
                        field_name: key,
                        field_value: item[key]
                    }
                })
            });
            res.push(reload);
        }
        return res;
    }

    async SearchGoodDesign(query: string, svrId: HSKnowledgeService) {
        const result = await this.Search(query, svrId);
        let newList = result.result_list.filter(x => x.score > 0.6);
        if (newList.length > 0) {
            return newList.map(x => {

                const stareIdx = x.content.indexOf("content:");
                const html = x.content.substring(stareIdx).replace("content:", "").trim();
                const style = x.content.match(/style:(.*?)\n/)?.[1];
                const industry = x.content.match(/industry:(.*?)\n/)?.[1];
                const userInput = x.content.match(/userInput:(.*?)\n/)?.[1];

                return {
                    userInput,
                    style,
                    industry,
                    html
                }
            });
        }
        else return [];
    }

    async Search(query: string, svrId: HSKnowledgeService) {
        const serviceId = svrId;
        const url = "api/knowledge/service/chat";

        const config = this.getReqParams(url, {
            service_resource_id: serviceId,
            messages: [
                {
                    "role": "user",
                    "content": query
                }
            ]
        });

        const res = await axios(config);
        const resData = res.data.data as HSKnowledgeResult;
        return resData;
    }

    async GetIndustry(userInput: string) {
        const model = LLMProvider.current.ZiJieDeepSeekV3;
        const output = await model.stream([
            new HumanMessage(`
                用户：${userInput}
                根据用户的输入分析用户的行业属性
                ## 输出
                服装|电商|零售

                - 仅仅输出行业属性，不要解释，不要其他内容
            `)
        ]);
        for await (const chunk of output) {
        }

        return model.lastFullResponse;
    }


    async GenImage(input: string, size: string, inputImages: string[]) {
        const model = LLMProvider.current.DoubaoSeedream40;
        model.prompt = input;
        // model.guidance_scale = 5;
        model.size = HS_ImageGenSize[size];
        const res = await model.invoke([]);
        return res;
    }
}